/*
 * ServiceView.java
 *
 * Created on Mar 21, 2010, 6:54:06 PM
 */
package assetl.desktop;

import java.util.ArrayList;
import java.util.AbstractMap;
import java.util.HashMap;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.JList;
import javax.swing.JLabel;
import javax.swing.DefaultListModel;
import javax.swing.AbstractButton;

import assetl.system.AssetLControl;
import assetl.system.DataPacket;
import assetl.system.PersonPacket;
import assetl.system.Person;
import assetl.system.Request;
import assetl.system.Checkout;
import assetl.system.User;

/**
 * Allows the user to schedule and checkout assets.
 *
 * @author Devin Doman
 */
public class ServiceView
   extends AssetView
{
   /**
    * The list model holding scheduled requests
    */
   private DefaultListModel mScheduledListModel;
   /**
    * The list model holding checked out requests
    */
   private DefaultListModel mCheckedOutListModel;
   /**
    * The list model holding assets in a scheduled request
    */
   private DefaultListModel mScheduledAssetsListModel;
   /**
    * The list model holding assets in a checked out request
    */
   private DefaultListModel mCheckedOutAssetsListModel;
   /**
    * Maps functionality to the button the causes it
    */
   AbstractMap<String, AbstractButton> mButtonMap;
   /**
    * Maps a functionality to a PacketGenerator that will
    * produce the DataPacket the function needs
    */
   AbstractMap<String, PacketGenerator> mPacketMap;

   /**
    * Constructor for the user interface
    *
    * @param pControl The controller for this view
    */
   public ServiceView(AssetLControl pControl)
   {
      super(pControl);

      mScheduledListModel = new DefaultListModel();
      mCheckedOutListModel = new DefaultListModel();
      mScheduledAssetsListModel = new DefaultListModel();
      mCheckedOutAssetsListModel = new DefaultListModel();
      initComponents();
      generateMap();
      generatePacketMap();

      mScheduledList.addListSelectionListener(new ListSelectionListener()
      {
         /**
          * Listens for when the value of a list selection has changed
          */
         public void valueChanged(ListSelectionEvent ev)
         {
            JList list = (JList) ev.getSource();
            //If nothing in the list is selected
            if (list.isSelectionEmpty())
            {
               //Enable CheckoutAsset function, which will prompt for assets
               enable("CheckoutAsset");
            }
            else
            {
               //Enable Checkout function
               enable("Checkout");
            }
         }
      });

      mCheckedOutList.addListSelectionListener(new ListSelectionListener()
      {
         /**
          * Listens for when the value of a list selection has changed
          */
         public void valueChanged(ListSelectionEvent ev)
         {
            // TODO: uncomment when extend is supported
            //enable("Extend");
         }
      });

      // TODO: uncomment when extend is supported
      mExtendBtn.setVisible(false);
   }

   /** This method is called from within the constructor to
    * initialize the form.
    * WARNING: Do NOT modify this code. The content of this method is
    * always regenerated by the Form Editor.
    */
   @SuppressWarnings("unchecked")
   // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
   private void initComponents() {

      mNameLbl = new javax.swing.JLabel();
      mCheckedOutScroll = new javax.swing.JScrollPane();
      mCheckedOutList = new javax.swing.JList();
      mScheduleScroll = new javax.swing.JScrollPane();
      mScheduledList = new javax.swing.JList();
      mCheckoutLbl = new javax.swing.JLabel();
      mRequestedLbl = new javax.swing.JLabel();
      mExtendBtn = new javax.swing.JButton();
      mScheduleBtn = new javax.swing.JButton();
      mCheckoutBtn = new javax.swing.JButton();
      mCancelBtn = new javax.swing.JButton();
      mCheckedOutAssetsScrollPane = new javax.swing.JScrollPane();
      mCheckedOutAssetList = new javax.swing.JList();
      mScheduledAssetScrollPane = new javax.swing.JScrollPane();
      mScheduledAssetList = new javax.swing.JList();
      mRemoveAssetBtn = new javax.swing.JButton();
      mAddAssetBtn = new javax.swing.JButton();

      setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

      mNameLbl.setText("Name");
      mNameLbl.setName("mNameLbl"); // NOI18N

      mCheckedOutScroll.setName("mCheckedOutScroll"); // NOI18N

      mCheckedOutList.setModel(mCheckedOutListModel);
      mCheckedOutList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
      mCheckedOutList.setName("mCheckedOutList"); // NOI18N
      mCheckedOutScroll.setViewportView(mCheckedOutList);

      mScheduleScroll.setName("mScheduleScroll"); // NOI18N

      mScheduledList.setModel(mScheduledListModel);
      mScheduledList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
      mScheduledList.setName("mScheduledList"); // NOI18N
      mScheduleScroll.setViewportView(mScheduledList);

      mCheckoutLbl.setText("Currently Checked out:");
      mCheckoutLbl.setName("mCheckoutLbl"); // NOI18N

      mRequestedLbl.setText("Currently Scheduled:");
      mRequestedLbl.setName("mRequestedLbl"); // NOI18N

      mExtendBtn.setText("Extend");
      mExtendBtn.setName("mExtendBtn"); // NOI18N

      mScheduleBtn.setText("+");
      mScheduleBtn.setName("mScheduleBtn"); // NOI18N

      mCheckoutBtn.setText("Checkout");
      mCheckoutBtn.setName("mCheckoutBtn"); // NOI18N

      mCancelBtn.setText("-");
      mCancelBtn.setName("mCancelBtn"); // NOI18N

      mCheckedOutAssetsScrollPane.setName("mCheckedOutAssetsScrollPane"); // NOI18N

      mCheckedOutAssetList.setModel(mCheckedOutAssetsListModel);
      mCheckedOutAssetList.setName("mCheckedOutAssetList"); // NOI18N
      mCheckedOutAssetsScrollPane.setViewportView(mCheckedOutAssetList);

      mScheduledAssetScrollPane.setName("mScheduledAssetScrollPane"); // NOI18N

      mScheduledAssetList.setModel(mScheduledAssetsListModel);
      mScheduledAssetList.setName("mScheduledAssetList"); // NOI18N
      mScheduledAssetScrollPane.setViewportView(mScheduledAssetList);

      mRemoveAssetBtn.setText("-");
      mRemoveAssetBtn.setName("mRemoveAssetBtn"); // NOI18N

      mAddAssetBtn.setText("+");
      mAddAssetBtn.setName("mAddAssetBtn"); // NOI18N

      javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
      getContentPane().setLayout(layout);
      layout.setHorizontalGroup(
         layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
         .addGroup(layout.createSequentialGroup()
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
               .addGroup(layout.createSequentialGroup()
                  .addGap(32, 32, 32)
                  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                     .addGroup(layout.createSequentialGroup()
                        .addComponent(mScheduleBtn)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(mCancelBtn)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 107, Short.MAX_VALUE)
                        .addComponent(mCheckoutBtn))
                     .addComponent(mRequestedLbl)
                     .addComponent(mScheduleScroll, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE)))
               .addGroup(layout.createSequentialGroup()
                  .addGap(21, 21, 21)
                  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                     .addComponent(mNameLbl)
                     .addGroup(layout.createSequentialGroup()
                        .addGap(10, 10, 10)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                           .addComponent(mCheckoutLbl)
                           .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                              .addComponent(mExtendBtn)
                              .addComponent(mCheckedOutScroll, javax.swing.GroupLayout.PREFERRED_SIZE, 235, javax.swing.GroupLayout.PREFERRED_SIZE)))))))
            .addGap(32, 32, 32)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
               .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                  .addComponent(mScheduledAssetScrollPane)
                  .addComponent(mCheckedOutAssetsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 155, Short.MAX_VALUE))
               .addGroup(layout.createSequentialGroup()
                  .addComponent(mAddAssetBtn)
                  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                  .addComponent(mRemoveAssetBtn)))
            .addGap(43, 43, 43))
      );
      layout.setVerticalGroup(
         layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
         .addGroup(layout.createSequentialGroup()
            .addGap(24, 24, 24)
            .addComponent(mNameLbl)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
            .addComponent(mCheckoutLbl)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
               .addComponent(mCheckedOutAssetsScrollPane, javax.swing.GroupLayout.Alignment.LEADING, 0, 0, Short.MAX_VALUE)
               .addComponent(mCheckedOutScroll, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 171, Short.MAX_VALUE))
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
               .addGroup(layout.createSequentialGroup()
                  .addComponent(mExtendBtn)
                  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 17, Short.MAX_VALUE)
                  .addComponent(mRequestedLbl)
                  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                  .addComponent(mScheduleScroll, javax.swing.GroupLayout.PREFERRED_SIZE, 183, javax.swing.GroupLayout.PREFERRED_SIZE))
               .addComponent(mScheduledAssetScrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 183, javax.swing.GroupLayout.PREFERRED_SIZE))
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
               .addComponent(mScheduleBtn)
               .addComponent(mCancelBtn)
               .addComponent(mCheckoutBtn)
               .addComponent(mRemoveAssetBtn)
               .addComponent(mAddAssetBtn))
            .addContainerGap())
      );

      pack();
   }// </editor-fold>//GEN-END:initComponents
   // Variables declaration - do not modify//GEN-BEGIN:variables
   /** Add asset from scheduled request button*/
   private javax.swing.JButton mAddAssetBtn;
   /**
   * Button to Cancel a scheduled Request
   */
   private javax.swing.JButton mCancelBtn;
   /** Holds Assets contained in a scheduled request*/
   private javax.swing.JList mCheckedOutAssetList;
   /** Scroll Pane for checked out assets list*/
   private javax.swing.JScrollPane mCheckedOutAssetsScrollPane;
   /**
   * Holds Checked out Requests
   */
   private javax.swing.JList mCheckedOutList;
   /**
   * A Scroll Pane for the Checked out JList
   */
   private javax.swing.JScrollPane mCheckedOutScroll;
   /**
   * Button to Checkout an asset
   */
   private javax.swing.JButton mCheckoutBtn;
   /**
   * Label for Checked out JList
   */
   private javax.swing.JLabel mCheckoutLbl;
   /**
   * Button to Extend a Checkout
   */
   private javax.swing.JButton mExtendBtn;
   /**
   * A place to put the name of the current person
   */
   private javax.swing.JLabel mNameLbl;
   /** Remove asset from scheduled request button*/
   private javax.swing.JButton mRemoveAssetBtn;
   /**
   * Label for scheduled JList
   */
   private javax.swing.JLabel mRequestedLbl;
   /**
   * Button to schedule an Asset
   */
   private javax.swing.JButton mScheduleBtn;
   /**
   * A Scroll Pane for the Scheduled JList
   */
   private javax.swing.JScrollPane mScheduleScroll;
   /** Holds Assets contained in a checked out request*/
   private javax.swing.JList mScheduledAssetList;
   /** Scroll Pane for scheduled assets list*/
   private javax.swing.JScrollPane mScheduledAssetScrollPane;
   /**
   * Holds Scheduled Requests
   */
   private javax.swing.JList mScheduledList;
   // End of variables declaration//GEN-END:variables

   /**
    * Gives access to the name label
    *
    * @return The name label
    */
   public JLabel getNameLbl()
   {
      return mNameLbl;
   }

   /**
    * Gives access to the checked out list
    *
    * @return The checked out list
    */
   public JList getCheckedOutList()
   {
      return mCheckedOutList;
   }

   /**
    * Gives access to the scheduled list
    *
    * @return The scheduled list
    */
   public JList getScheduledList()
   {
      return mScheduledList;
   }

   /**
    * Returns the current DataPacket
    *
    * @return The DataPacket
    */
   public DataPacket getDataPacket()
   {
      return mPacket;
   }

   /**
    * Creates the map between functions and the buttons that causes them
    */
   public void generateMap()
   {
      mButtonMap = new HashMap<String, AbstractButton>();
      mButtonMap.put("Cancel", mCancelBtn);
      mButtonMap.put("Checkout", mCheckoutBtn);
      mButtonMap.put("CheckoutAsset", mCheckoutBtn);
      mButtonMap.put("Extend", mExtendBtn);
      mButtonMap.put("ScheduleAsset", mScheduleBtn);
   }

   /**
    * Creates the map between functions and the PacketGenerator it needs
    */
   public void generatePacketMap()
   {
      PacketGenerator gen = null;
      mPacketMap = new HashMap<String, PacketGenerator>();

      gen = new ServiceStringGrabber(this);
      mPacketMap.put("ScheduleAsset", gen);
      mPacketMap.put("CheckoutAsset", gen);
      gen = new ServiceRequestGrabber(this);
      mPacketMap.put("Checkout", gen);
      mPacketMap.put("Cancel", gen);
   }

   /**
    * Allows control of the visibility of Admin components in the view
    *
    * @param pIsAdmin True if the admin components are to be set to visible
    */
   @Override
   public void setAdminComponents(int pIsAdmin)
   {
      super.setAdminComponents(pIsAdmin);
      mCheckoutBtn.setVisible(pIsAdmin <= User.GATEKEEPER);
   }

   /**
    * Updates the views display of the model
    */
   public void updateData()
   {
      //Clear the JLists
      mScheduledListModel.clear();
      mCheckedOutListModel.clear();
      mScheduledAssetsListModel.clear();
      mCheckedOutAssetsListModel.clear();
      ArrayList<Request> requests = null;

      //
      // Use the person id stored in the packet to get from the model
      // the most recent data about the person, then update the packet
      // and the labels
      //

      //Update the person labels
      PersonPacket tempPacket = (PersonPacket) mPacket;
      Person tempPerson = mControl.getPerson(tempPacket.getPerson().getID());
      tempPacket.setPerson(tempPerson);
      mPacket = tempPacket;
      mNameLbl.setText(tempPerson.getID() + ": " + tempPerson.toStringName());


      requests = (ArrayList<Request>) mControl.getScheduledRequests(tempPerson);

      if (requests != null)
      {
         for (Request curr : requests)
         {
            mScheduledListModel.addElement(curr);

            for (Checkout out : curr.getCheckouts())
            {
               mScheduledAssetsListModel.addElement(out.getAsset());
            }
         }
      }

      requests = (ArrayList<Request>) mControl.getCheckedOutRequests(tempPerson);

      if (requests != null)
      {
         for (Request curr : requests)
         {
            mCheckedOutListModel.addElement(curr);

            for (Checkout out : curr.getCheckouts())
            {
               mCheckedOutAssetsListModel.addElement(out.getAsset());
            }
         }
      }

   }

   /**
    * Grabs all pertainent data from the fields and sets them in
    * a DataPacket object. This DataPacket is then returned by the
    * method.
    *
    * @param pFunction The function that needs the DataPacket
    * @return The DataPacket that has been set
    */
   public DataPacket grabDataPacket(String pFunction)
   {
      ServiceDataGrabber grabber = null;
      grabber = (ServiceDataGrabber) mPacketMap.get(pFunction);
      return grabber.grab();
   }

   /**
    * Enables functionality passed in for this view.
    */
   public void enable(String pFunction)
   {
      //Enable a FunctionListener for the button
      enable(pFunction, mButtonMap.get(pFunction), "Function");
   }

   /**
    * The entry point for this view
    */
   public void run()
   {
      enable("ScheduleAsset");
      enable("CheckoutAsset");
      enable("Cancel");
   }
}
